#include "fccu.h"
#include "qpc_stub.h"
#include <stdio.h>
#include <string.h>
#include <time.h>

/* AO实例和事件队列 */
#define AO_QUEUE_LEN 8U
static struct QEvt* major_evt_queue[AO_QUEUE_LEN];   /* 主AO事件队列 */
static struct QEvt* minor_evt_queue[AO_QUEUE_LEN];   /* 次AO事件队列 */
static struct QActive major_ao, minor_ao;            /* AO对象 */

/* 主AO事件分发函数 */
static void major_dispatch(struct QActive * const me, struct QEvt const * const e)
{
    (void)me;
    if(e->sig == Q_USER_SIG)
    {
        Fccu_ProcessPostEvent(&major_ao, 0U); /* 处理主优先级故障 */
    }
    QF_gc((struct QEvt*)e);
}

/* 次AO事件分发函数 */
static void minor_dispatch(struct QActive * const me, struct QEvt const * const e)
{
    (void)me;
    if(e->sig == Q_USER_SIG)
    {
        Fccu_ProcessPostEvent(&minor_ao, 1U); /* 处理次优先级故障 */
    }
    QF_gc((struct QEvt*)e);
}

/* AO对象构造函数 */
void Fccu_AO_Ctor(void)
{
    memset(&major_ao, 0, sizeof(major_ao));
    memset(&minor_ao, 0, sizeof(minor_ao));
    major_ao.dispatch = major_dispatch;
    minor_ao.dispatch = minor_dispatch;
    major_ao.ao_priority = 0U;
    minor_ao.ao_priority = 1U;
    major_ao.queue = major_evt_queue;
    minor_ao.queue = minor_evt_queue;
    major_ao.queue_len = AO_QUEUE_LEN;
    minor_ao.queue_len = AO_QUEUE_LEN;
    major_ao.queue_head = major_ao.queue_tail = 0U;
    minor_ao.queue_head = minor_ao.queue_tail = 0U;
}

/* 溢出回调示例 */
void my_overflow_callback(void)
{
    printf("[Demo] Queue overflow callback triggered!\n");
}

/* 用户自定义钩子示例 */
int32_t my_custom_hook(uint32_t code, uint64_t detail, bool first)
{
    printf("[Demo] my_custom_hook: code=0x%08x, detail=0x%llx, first=%d\n", code, (unsigned long long)detail, first ? 1 : 0);
    return 888;
}

/* 主函数，演示FCCU功能 */
int main(void)
{
    printf("=== FCCU Demo Start ===\n");

    Fccu_AO_Ctor();    /* 初始化AO对象 */
    Fccu_Init();       /* 初始化FCCU模块 */

    /* 设置溢出回调 */
    Fccu_SetQueueOverflowCallback(my_overflow_callback);

    /* 注册自定义钩子到故障索引3 */
    Fccu_RegisterUserHook(3U, my_custom_hook);

    /* 上报不同优先级的故障点 */
    Fccu_ReportFaultPoint(1U, (uint64_t)time(NULL), 0U);
    Fccu_ReportFaultPoint(2U, (uint64_t)time(NULL) + 1U, 1U);
    Fccu_ReportFaultPoint(3U, (uint64_t)time(NULL) + 2U, 0U);

    /* 查询活跃故障数量 */
    Fccu_GetActiveFaults();

    /* 主动清除一个故障 */
    Fccu_ClearFault(1U);

    /* 再次查询活跃故障数量 */
    Fccu_GetActiveFaults();

    /* 直接处理各优先级队列 */
    Fccu_ProcessPostEvent(&major_ao, 0U);
    Fccu_ProcessPostEvent(&minor_ao, 1U);

    printf("=== FCCU Demo End ===\n");
    return 0;
}